<?php

namespace Biz\service\salesRebate;

use Biz\model\salesRebate\SalesWithdrawalRecord as mSalesWithdrawalRecord;
use Biz\model\salesRebate\SalesAccount as mSalesAccount;
use Biz\model\salesRebate\SalesAccountLog as mSalesAccountLog;
use Biz\model\salesRebate\SalesPersonal as mSalesPersonal;
use Biz\tools\ShopArea;
use Doraemon\service\User;
use Biz\pockets\excel\DownExcel;
use Doraemon\tools\Log;

/**
 * @deprecated
 */
class SalesWithdrawal
{

    /**
     * 生成个人账户申请提现单
     * @param $uid uid
     * @param $bank 账户个人资料银行信息
     * @param bool $isSys 是否系统(第一次非系统操作)
     * @return bool
     * @throws
     */
    public static function createPersonalBill($uid, $bank, $isSys = false)
    {
        $type = mSalesWithdrawalRecord::TYPE_PERSONAL;
        if (!$bank) {
            Log::debug('请填写完整的个人账户信息#uid:' . $uid);
            return false;
        }
        $accountInfo = mSalesAccount::getOneByWhere('*', ['uid' => $uid, 'type' => $type]);
        if (!$accountInfo) {
            mSalesAccount::addData(['uid' => $uid, 'type' => $type, 'status' => mSalesAccount::STATUS_NORMAL]);
            return false;
        }
        if ($accountInfo['balance'] <= 0) {
            Log::debug('申请提现金额不能小于等于0#uid:' . $uid);
            return false;
        }
        $data = [
            'uid' => $uid,
            'type' => $type,
            'withdrawal_code' => mSalesWithdrawalRecord::createWithdrawalCode($uid, $type),
            'withdrawal_amount' => $accountInfo['balance'],
            'status' => mSalesWithdrawalRecord::STATUS_NORMAL,
            'name' => $bank['name'],
            'id_card_no' => $bank['id_card_no'],
            'bank_no' => $bank['bank_no'],
            'telephone' => $bank['telephone'],
        ];
        $withdrawalRecordList = [];
        if ($isSys) {
            $withdrawalRecordList = mSalesWithdrawalRecord::getAllByWhere('*', ['uid' => $uid, 'type' => $type, 'status[!]' => mSalesWithdrawalRecord::STATUS_ACCOUNTED]);
        }
        try {
            $result = mSalesAccount::action(function () use ($uid, $accountInfo, $type, $isSys, $withdrawalRecordList, $data) {
                if ($isSys && $withdrawalRecordList) {//存在未入账的，则需要把申请单置为失效状态，同时，退换提现金额到用户账户可提现金额当中
                    foreach ($withdrawalRecordList as $row) {
                        $withdrawalAmount = $row['withdrawal_amount'];
                        $result = mSalesWithdrawalRecord::updateData(['status' => mSalesWithdrawalRecord::STATUS_INVALID], ['id' => $row['id']]);
                        if ($result) {
                            $logArr = [
                                'operate_type' => mSalesAccountLog::OPERATE_TYPE_WITHDRAWAL_INVALID,
                                'operate_user_type' => mSalesAccountLog::OPERATE_USER_TYPE_SYS,
                                'operate_user_id' => 0,
                                'withdrawal_code' => $row['withdrawal_code'],
                            ];
                            $result = mSalesAccount::updateAccount($accountInfo, $uid, $type, $withdrawalAmount, 0, $logArr);
                            if (!$result) {
                                throw new \Exception('更新公司账户可提现金额失败');
                            }
                        } else {
                            throw new \Exception('发现有未入账的个人提现申请单，需要置为失效，但更新失败');
                        }
                    }
                }
                $record = mSalesWithdrawalRecord::addData($data);
                if ($record) {
                    $logArr = [
                        'operate_type' => mSalesAccountLog::OPERATE_TYPE_WITHDRAWAL_APPLY,
                        'operate_user_type' => mSalesAccountLog::OPERATE_USER_TYPE_USER,
                        'operate_user_id' => $uid,
                        'withdrawal_code' => $data['withdrawal_code'],
                    ];
                    $result = mSalesAccount::updateAccount($accountInfo, $uid, $type, bcsub(0, $accountInfo['balance'], 2), 0, $logArr);
                    if (!$result) {
                        throw new \Exception('更新个人账户可提现金额失败');
                    }
                } else {
                    throw new \Exception('生成个人账户提现申请单失败');
                }
                return true;
            });
        } catch (\Exception $e) {
            $msg = '生成个人账户提现申请单失败#' . '#uid:' . $uid . '#personal_info:' . $bank . '#isSys:' . $isSys . '#msg:' . json_encode([
                    'e_file' => $e->getFile(),
                    'e_line' => $e->getLine(),
                    'e_msg' => $e->getMessage()
                ], JSON_UNESCAPED_UNICODE);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_SYSTEM,
                "content" => $msg
            ], Queue::QUEUE_BIZ);
            Log::debug($msg);
            return [];
        }
        return $result ? $data : [];
    }

    /**
     * 生成公司账户申请提现单
     * @param $uid uid
     * @param $bank 账户个人资料银行信息
     * @return bool
     * @throws
     */
    public static function createCompanyBill($uid, $amount, $bank)
    {
        $type = mSalesWithdrawalRecord::TYPE_COMPANY;
        $accountInfo = mSalesAccount::getOneByWhere('*', ['uid' => $uid, 'type' => $type]);
        if (!$accountInfo) {
            mSalesAccount::addData(['uid' => $uid, 'type' => $type, 'status' => mSalesAccount::STATUS_NORMAL]);
            return false;
        }
        if ($amount <= 0) {
            Log::debug('申请提现金额不能小于等于0#uid:' . $uid);
            return false;
        }
        if ($amount > $accountInfo['balance']) {
            Log::debug('申请提现金额不能大于账户可提现金额#uid:' . $uid);
            return false;
        }
        if (!$bank) {
            Log::debug('请填写完整的公司账户信息#uid:' . $uid);
            return false;
        }
        $data = [
            'uid' => $uid,
            'type' => $type,
            'withdrawal_code' => mSalesWithdrawalRecord::createWithdrawalCode($uid, $type),
            'withdrawal_amount' => $amount,
            'status' => mSalesWithdrawalRecord::STATUS_NORMAL,
            'name' => $bank['name'],
            'bank_no' => $bank['bank_no'],
            'bank_name' => $bank['bank_name'],
            'province' => empty($bank['province']) ? '' : ShopArea::locationId2Name($bank['province']),
            'city' => empty($bank['city']) ? '' : ShopArea::locationId2Name($bank['city']),
            'area' => empty($bank['area']) ? '' : ShopArea::locationId2Name($bank['area']),
            'subbranch' => $bank['subbranch'],
        ];
        try {
            $result = mSalesAccount::action(function () use ($uid, $accountInfo, $amount, $type, $data) {
                $record = mSalesWithdrawalRecord::addData($data);
                if ($record) {
                    $logArr = [
                        'operate_type' => mSalesAccountLog::OPERATE_TYPE_WITHDRAWAL_APPLY,
                        'operate_user_type' => mSalesAccountLog::OPERATE_USER_TYPE_USER,
                        'operate_user_id' => $uid,
                        'withdrawal_code' => $data['withdrawal_code'],
                    ];
                    $result = mSalesAccount::updateAccount($accountInfo, $uid, $type, bcsub(0, abs($amount), 2), 0, $logArr);
                    if (!$result) {
                        throw new \Exception('更新公司账户可提现金额失败');
                    }
                } else {
                    throw new \Exception('生成公司账户提现申请单失败');
                }
                return true;
            });
        } catch (\Exception $e) {
            $msg = '生成公司账户提现申请单失败#' . '#uid:' . $uid . '#company_info:' . $bank . '#msg:' . json_encode([
                    'e_file' => $e->getFile(),
                    'e_line' => $e->getLine(),
                    'e_msg' => $e->getMessage()
                ], JSON_UNESCAPED_UNICODE);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_SYSTEM,
                "content" => $msg
            ], Queue::QUEUE_BIZ);
            Log::debug($msg);
            return [];
        }
        return $result ? $data : [];
    }

    /**
     * 已转账（管理后台专用）
     * @param $withdrawalCode
     * @param $adminId
     * @param $receiptNumber 银行回单编号
     * @return bool
     */
    public static function admAccountedRecord($withdrawalCode, $adminId, $receiptNumber)
    {
        $result = false;
        $recordInfo = mSalesWithdrawalRecord::getOneByWhere('*', ['withdrawal_code' => $withdrawalCode, 'status[!]' => [mSalesWithdrawalRecord::STATUS_INVALID, mSalesWithdrawalRecord::STATUS_DELETE]]);
        if ($recordInfo) {
            $type = $recordInfo['type'];
            $uid = $recordInfo['uid'];
            $isSigned = false;
            if ($type == mSalesAccount::TYPE_PERSONAL) {
                $isSigned = mSalesPersonal::IsSigned($uid);
            }
            $accountInfo = mSalesAccount::getOneByWhere('*', ['uid' => $uid, 'type' => $type]);
            $result = mSalesAccount::action(function () use ($uid, $type, $accountInfo, $recordInfo, $adminId, $receiptNumber, $withdrawalCode, $isSigned) {
                $result = false;
                if (!$receiptNumber) {
                    throw new \Exception('请输入银行回单编号', 0);
                }
                if ($recordInfo['status'] < mSalesWithdrawalRecord::STATUS_ACCOUNTED) {
                    if (mSalesAccountLog::hasAccounted($uid, $type, $withdrawalCode, $receiptNumber)) {
                        throw new \Exception('已经转账了，请勿重复操作', 0);
                    }
                    $result = mSalesWithdrawalRecord::updateData(['status' => mSalesWithdrawalRecord::STATUS_ACCOUNTED], ['id' => $recordInfo['id']]);
                    if ($result) {
                        //更新用户累计已提现总金额
                        $logArr = [
                            'operate_type' => mSalesAccountLog::OPERATE_TYPE_WITHDRAWAL_SUCCESS,
                            'operate_user_type' => mSalesAccountLog::OPERATE_USER_TYPE_ADMIN,
                            'operate_user_id' => $adminId,
                            'receipt_number' => $receiptNumber,
                            'withdrawal_code' => $withdrawalCode
                        ];
                        $result = mSalesAccount::updateAccount($accountInfo, $uid, $type, 0, 0, $logArr, $recordInfo['withdrawal_amount']);
                    }
                } else {
                    throw new \Exception('当前提现申请记录状态不能进行已转账操作#status:' . $recordInfo['status'] . '#type:' . $type, 0);
                }
                if ($type == mSalesAccount::TYPE_PERSONAL && !$isSigned) {
                    $result = mSalesPersonal::updateData(['status' => mSalesPersonal::STATUS_SIGNED], ['uid' => $uid]);
                }
                return $result;
            });
        }
        return $result;
    }

    /**
     * 已收发票（管理后台专用）
     * @param $withdrawalCode
     * @param $invoiceAmount 发票金额
     * @param $invoiceType 发票类型
     * @param $invoiceNumber 发票编号
     * @return bool
     */
    public static function admAcceptedInvoice($withdrawalCode, $invoiceAmount, $invoiceType, $invoiceNumber)
    {
        $result = false;
        $recordInfo = mSalesWithdrawalRecord::getOneByWhere('*', ['withdrawal_code' => $withdrawalCode, 'status[!]' => [mSalesWithdrawalRecord::STATUS_INVALID, mSalesWithdrawalRecord::STATUS_DELETE]]);
        if ($recordInfo) {
            $type = $recordInfo['type'];
            $uid = $recordInfo['uid'];
            $result = mSalesAccount::action(function () use ($uid, $type, $recordInfo, $invoiceType, $invoiceAmount, $withdrawalCode, $invoiceNumber) {
                $result = false;
                if ($recordInfo['type'] == mSalesWithdrawalRecord::TYPE_COMPANY && $recordInfo['status'] == mSalesWithdrawalRecord::STATUS_NORMAL) {
                    $result = mSalesWithdrawalRecord::updateData(
                        [
                            'status' => mSalesWithdrawalRecord::STATUS_ACCOUNTING,
                            'invoice_amount' => $invoiceAmount,
                            'invoice_type' => $invoiceType,
                            'invoice_number' => $invoiceNumber
                        ],
                        ['id' => $recordInfo['id']]
                    );
                } else {
                    throw new \Exception('当前提现申请记录状态不能进行已收发票操作#status:' . $recordInfo['status'] . '#type:' . $type, 0);
                }
                return $result;
            });
        }
        return $result;
    }


    /**
     * 已失效（管理后台专用）
     * @param $withdrawalCode
     * @param $status
     * @param $adminId
     * @param string $receiptNumber 银行回单编号
     * @param int $invoiceType 发票类型
     * @param string $invoiceNumber 发票编号
     * @return bool
     */
    public static function admInvalidedRecord($withdrawalCode, $status, $adminId, $receiptNumber = '', $invoiceType = 0, $invoiceNumber = '')
    {
        $result = false;
        $recordInfo = mSalesWithdrawalRecord::getOneByWhere('*', ['withdrawal_code' => $withdrawalCode, 'status[!]' => [mSalesWithdrawalRecord::STATUS_INVALID, mSalesWithdrawalRecord::STATUS_DELETE]]);
        if ($recordInfo) {
            $type = $recordInfo['type'];
            $uid = $recordInfo['uid'];
            $accountInfo = mSalesAccount::getOneByWhere('*', ['uid' => $uid, 'type' => $type]);
            $result = mSalesAccount::action(function () use ($uid, $status, $type, $accountInfo, $recordInfo, $adminId, $receiptNumber, $withdrawalCode) {
                $result = false;
                if ($recordInfo['status'] < mSalesWithdrawalRecord::STATUS_ACCOUNTED) {
                    if (mSalesAccountLog::hasOperated($uid, $type, $withdrawalCode, mSalesAccountLog::OPERATE_TYPE_WITHDRAWAL_INVALID)) {
                        throw new \Exception('已经操作过失效，请勿重复操作', 0);
                    }
                    $result = mSalesWithdrawalRecord::updateData(['status' => mSalesWithdrawalRecord::STATUS_INVALID], ['id' => $recordInfo['id']]);
                    if ($result) {
                        //返回申请单提现金额到用户可提现金额
                        $logArr = [
                            'operate_type' => mSalesAccountLog::OPERATE_TYPE_WITHDRAWAL_INVALID,
                            'operate_user_type' => mSalesAccountLog::OPERATE_USER_TYPE_ADMIN,
                            'operate_user_id' => $adminId,
                            'withdrawal_code' => $withdrawalCode
                        ];
                        mSalesAccount::updateAccount($accountInfo, $uid, $type, $recordInfo['withdrawal_amount'], 0, $logArr);
                    }
                } else {
                    throw new \Exception('当前提现申请记录状态不能进行已失效操作#status:' . $recordInfo['status'] . '#type:' . $type, 0);
                }
                return $result;
            });
        }
        return $result;
    }

    public static function admGetPersonList($params)
    {
        $where = $params['AND'];
        $where['type'] = mSalesWithdrawalRecord::TYPE_PERSONAL;
        $status = $where['status'];
        switch ($status) {
            case 0:
                unset($where['status']);
                break;
            case 1:
                $where['status'] = mSalesWithdrawalRecord::STATUS_NORMAL;
                break;
            case 2:
                $where['status'] = mSalesWithdrawalRecord::STATUS_ACCOUNTED;
                break;
            case 3:
                $where['status'] = mSalesWithdrawalRecord::STATUS_INVALID;
                break;
        }
        $recordList = mSalesWithdrawalRecord::getAllByWhere('*', [
            'AND' => $where,
            'LIMIT' => $params['LIMIT'],
            'ORDER' => $params['ORDER']
        ]);
        $total = mSalesWithdrawalRecord::getAllCount($where);
        $list = self::_formatAdmRecordList($recordList);
        return ['list' => $list, 'total' => $total];
    }

    public static function admGetCompanyList($params)
    {
        $where = $params['AND'];
        $where['type'] = mSalesWithdrawalRecord::TYPE_COMPANY;
        $status = $where['status'];
        switch ($status) {
            case 0:
                unset($where['status']);
                break;
            case 1:
                $where['status'] = mSalesWithdrawalRecord::STATUS_NORMAL;
                break;
            case 2:
                $where['status'] = mSalesWithdrawalRecord::STATUS_ACCOUNTING;
                break;
            case 3:
                $where['status'] = mSalesWithdrawalRecord::STATUS_ACCOUNTED;
                break;
            case 4:
                $where['status'] = mSalesWithdrawalRecord::STATUS_INVALID;
                break;
        }
        $recordList = mSalesWithdrawalRecord::getAllByWhere('*', [
            'AND' => $where,
            'LIMIT' => $params['LIMIT'],
            'ORDER' => $params['ORDER']
        ]);
        $total = mSalesWithdrawalRecord::getAllCount($where);
        $list = self::_formatAdmRecordList($recordList);
        return ['list' => $list, 'total' => $total];
    }

    public static function admExportRecord($type, $where)
    {
        if ($type == 1) {
            $where['type'] = mSalesWithdrawalRecord::TYPE_PERSONAL;
            $where['status'] = mSalesWithdrawalRecord::STATUS_NORMAL;
            $recordList = mSalesWithdrawalRecord::getAllByWhere('*', $where);
            $data = [];
            $headers = [
                ['自助签约个人银行账户批量打款模板(单个批次文件最大支持10000条订单，单笔订单最大支持金额可在『商户中心-合作信息』中查看。请勿修改此条信息。)	', '', '', '', '', ''],
                ['批次号', '总笔数', '总金额(元)', '', '', ''],
                ['', '', '', '', '', ''],
                ['商户订单号(非必填)', '收款账号(个人银行卡号)', '收款户名(真实姓名必填)', '身份证号(必填)', '联系电话(手机号，必填)', '打款金额(元)'],
            ];
            $mergeHeader = ['A1:F1'];
            $letter = range('A', 'F');
            $excelObj = new DownExcel();
            $excelObj->setFileName('转账模版' . time());
            $excelObj->setSheetTitle('转账模版');
            //设置列宽
            $widths = [
                'A' => 20,
                'B' => 35,
                'C' => 20,
                'D' => 35,
                'E' => 20,
                'F' => 30,
            ];
            $excelObj->setWidth($widths);
            //默认单元格居中
            $excelObj->setDefaultStyleAlignment();

            $excelObj->setTextFormat('A');
            $excelObj->setTextFormat('B');
            $excelObj->setTextFormat('C');
            $excelObj->setTextFormat('D');
            $excelObj->setTextFormat('E');
            $excelObj->setTextFormat('F');
            $allCount = 0;
            $allAmount = 0;
            foreach ($recordList as $row) {
                $data[] = [
                    'withdrawal_code' => $row['withdrawal_code'],
                    'bank_no' => $row['bank_no'],
                    'name' => $row['name'],
                    'id_card_no' => $row['id_card_no']."\t",
                    'telephone' => $row['telephone'],
                    'withdrawal_amount' => $row['withdrawal_amount']
                ];
                $allAmount = bcadd($allAmount, $row['withdrawal_amount'], 2);
                $allCount++;
            }
            $headers[2][1] = $allCount;
            $headers[2][2] = $allAmount;
            foreach ($letter as $key => $value) {
                //设置字体
                $excelObj->setFrontName($value);
                //设置加粗
                $excelObj->setFrontBold($value . '4');
                //设置大小
                $excelObj->setFrontSize($value);
                //保护单元格
                //$excelObj->protectCells($value . '1:' . $value . (count($array) + 1));
            }
            $excelObj->create($data, $headers, null, '', [], [], $mergeHeader);
        } else if ($type == 2) {
            $where['type'] = mSalesWithdrawalRecord::TYPE_COMPANY;
            $where['status'] = mSalesWithdrawalRecord::STATUS_ACCOUNTING;
            $recordList = mSalesWithdrawalRecord::getAllByWhere('*', $where);
            $data = [];
            $header = ['提现申请码', '银行账号', '公司名称', '支行', '省', '市', '区', '提现金额', '银行名称'];
            $letter = range('A', 'I');
            $excelObj = new DownExcel();
            $excelObj->setFileName('转账模版' . time());
            $excelObj->setSheetTitle('转账模版');
            //设置列宽
            $widths = [
                'A' => 35,
                'B' => 35,
                'C' => 35,
                'D' => 30,
                'E' => 20,
                'F' => 20,
                'G' => 20,
                'H' => 25,
                'I' => 30,
            ];
            $excelObj->setWidth($widths);
            //默认单元格居中
            $excelObj->setDefaultStyleAlignment();
            $excelObj->freezePane('A1');//冻结窗口

            //设置货币形式
            $excelObj->setTextFormat('A');
            $excelObj->setTextFormat('H');
            foreach ($recordList as $row) {
                $data[] = [
                    'withdrawal_code' => $row['withdrawal_code'],
                    'bank_no' => $row['bank_no'],
                    'name' => $row['name'],
                    'subbranch' => $row['subbranch'],
                    'province' => $row['province'],
                    'city' => $row['city'],
                    'area' => $row['area'],
                    'withdrawal_amount' => $row['withdrawal_amount'],
                    'bank_name' => $row['bank_name'],
                ];
            }
            foreach ($letter as $key => $value) {
                //设置字体
                $excelObj->setFrontName($value);
                //设置加粗
                $excelObj->setFrontBold($value . '1');
                //设置大小
                $excelObj->setFrontSize($value);
                //保护单元格
                //$excelObj->protectCells($value . '1:' . $value . (count($array) + 1));
            }
            $excelObj->create($data, $header);
        }
    }

    private static function _formatAdmRecordList($recordList)
    {
        $list = [];
        $uids = array_column($recordList, 'uid');
        $users = User::getUsers($uids);
        foreach ($recordList as $row) {
            $recordInfo = [
                'id' => $row['id'],
                'uid' => $row['uid'],
                'user_name' => $users[$row['uid']]['nick'],
                'name' => $row['name'],
                'telephone' => $row['telephone'],
                'withdrawal_code' => $row['withdrawal_code'],
                'withdrawal_amount' => $row['withdrawal_amount'],
                'status' => $row['status'],
                'addtime' => $row['addtime']
            ];
            if ($row['type'] == mSalesWithdrawalRecord::TYPE_PERSONAL) {
                $recordInfo['status_desc'] = mSalesWithdrawalRecord::$personStatus[$row['status']];
            }
            if ($row['type'] == mSalesWithdrawalRecord::TYPE_COMPANY) {
                $recordInfo['status_desc'] = mSalesWithdrawalRecord::$companyStatus[$row['status']];
                $recordInfo['invoice_amount'] = $row['invoice_amount'];
                $recordInfo['invoice_type'] = $row['invoice_type'];
                $recordInfo['invoice_number'] = $row['invoice_number'];
            }
            $list[] = $recordInfo;
        }
        return $list;
    }
}
